
/*
 * Copyright (c) 2006-2009 by Roland Riegel <feedback@roland-riegel.de>
 * and (c) 2010 by Joni Lindqvist
 * 
 * This file is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <string.h>
#include <avr/pgmspace.h>
#include <avr/sleep.h>
#include "fat.h"
#include "fat_config.h"
#include "partition.h"
#include "sd_raw.h"
#include "sd_raw_config.h"
#include "uart.h"

#define DEBUG 0

static uint8_t read_line(char* buffer, uint8_t buffer_length);
static uint32_t strtolong(const char* str);
static uint8_t find_file_in_dir(struct fat_fs_struct* fs, struct fat_dir_struct* dd, const char* name, struct fat_dir_entry_struct* dir_entry);
static struct fat_file_struct* open_file_in_dir(struct fat_fs_struct* fs, struct fat_dir_struct* dd, const char* name); 
static uint8_t print_disk_info(const struct fat_fs_struct* fs);

int main()
{
    /* we will just use ordinary idle mode */
    set_sleep_mode(SLEEP_MODE_IDLE);

    /* setup uart */
    //uart_init();
	
	DDRA=0xFE; //SET PORTA as debug port
    
	while(1)
    {
        /* setup sd card slot */
        if(!sd_raw_init())
        {

			PORTA=0x02;
#if DEBUG
            uart_puts_p(PSTR("MMC/SD initialization failed\n"));
#endif
            continue;
        }

        /* open first partition */
        struct partition_struct* partition = partition_open(sd_raw_read,
                                                            sd_raw_read_interval,
                                                            sd_raw_write,
                                                            sd_raw_write_interval,
                                                            0
                                                           );

        if(!partition)
        {
            /* If the partition did not open, assume the storage device
             * is a "superfloppy", i.e. has no MBR.
             */
            partition = partition_open(sd_raw_read,
                                       sd_raw_read_interval,
                                       sd_raw_write,
                                       sd_raw_write_interval,
                                       -1
                                      );
            if(!partition)
            {
				PORTA=0x04;
#if DEBUG
                uart_puts_p(PSTR("opening partition failed\n"));
#endif
                continue;
            }
        }

        /* open file system */
        struct fat_fs_struct* fs = fat_open(partition);
        if(!fs)
        {
			PORTA=0x08;
#if DEBUG
            uart_puts_p(PSTR("opening filesystem failed\n"));
#endif
            continue;
        }

        /* open root directory */
        struct fat_dir_entry_struct directory;
        fat_get_dir_entry_of_path(fs, "/", &directory);

        struct fat_dir_struct* dd = fat_open_dir(fs, &directory);
        if(!dd)
        {
			PORTA=0x0F;
#if DEBUG
            uart_puts_p(PSTR("opening root directory failed\n"));
#endif
            continue;
        }
        


/*** INIT STOPS HERE **/
		//create new file
		struct fat_dir_entry_struct file_entry;
        if(!fat_create_file(dd, "1", &file_entry))
        {
        	PORTA=0x20;
        }
		
		//Open file for writing		
		struct fat_file_struct* fd = open_file_in_dir(fs, dd, "1");
        if(!fd)
        {
        	PORTA=0x40;
			continue;
        }
		
		int32_t offset = 0;
		if(!fat_seek_file(fd, &offset, FAT_SEEK_SET))
        {
			PORTA=0x80;
        	fat_close_file(fd);
            continue;
        }
		
		char buffer[24]="It's alive!!!";
		uint8_t data_len=12; //actual length of buffer
		                 
        /* write text to file */
		if(fat_write_file(fd, (uint8_t*) buffer, data_len) != data_len)
        {
        	PORTA=0xFE;
			break;
        }
        
		fat_close_file(fd);

        /* close file system */
        fat_close(fs);

        /* close partition */
        partition_close(partition);
    }
    
    return 0;
}


uint32_t strtolong(const char* str)
{
    uint32_t l = 0;
    while(*str >= '0' && *str <= '9')
        l = l * 10 + (*str++ - '0');

    return l;
}

uint8_t find_file_in_dir(struct fat_fs_struct* fs, struct fat_dir_struct* dd, const char* name, struct fat_dir_entry_struct* dir_entry)
{
    while(fat_read_dir(dd, dir_entry))
    {
        if(strcmp(dir_entry->long_name, name) == 0)
        {
            fat_reset_dir(dd);
            return 1;
        }
    }

    return 0;
}

struct fat_file_struct* open_file_in_dir(struct fat_fs_struct* fs, struct fat_dir_struct* dd, const char* name)
{
    struct fat_dir_entry_struct file_entry;
    if(!find_file_in_dir(fs, dd, name, &file_entry))
        return 0;

    return fat_open_file(fs, &file_entry);
}



